/**
 * googleMap
 * This JavaScript file is for Canvas view.
 */
var map;
var markersArrayUser = [];
var markersArrayFetched = [];
var spn = {};
var locationCenter;
var zoomLevel;
var autocomplete;
var pressed = 0;
var bufferGlobal = {};
var loc;
var lhpsObj;
var footer;
var obj;

var BACK_END = 'back';

var RES_STRING = "HXAKCnJlc3RhdXJhbnQQAiINCgAQ5sz9h_j_____AQ";
var CAFE_STRING = "F1gKBGNhZmUQAiINCgAQmf_nhPj_____AQ";
var HOS_STRING = "G2gKCGhvc3BpdGFsEAIiDQoAEJn__4f4_____wE";

var RES_ICON = "http://www.google.com/mapmaker/mapfiles/red-bloodcell-medium.png";
var HOS_ICON = "http://gmapgame.googlecode.com/svn/trunk/yellowcircle.jpg";
var CAFE_ICON = "http://gmapgame.googlecode.com/svn/trunk/greencircle.jpg";
var RES_USER_ICON = "http://gmapgame.googlecode.com/svn/trunk/marker3.png";
var HOS_USER_ICON = "http://gmapgame.googlecode.com/svn/trunk/marker2.png";
var CAFE_USER_ICON = "http://gmapgame.googlecode.com/svn/trunk/marker1.png";

var categoryString = RES_STRING;


var imgUrl;
var markerUrl;

function CategoryMapType(tileSize) {
    var me = this;
    this.tileSize = tileSize;
    google.maps.event.addListener(map, 'mousemove', function(event){
	    if (bufferGlobal.pressed) {
		me.fetchDataIfNeeded(event);
	    }
	});
    this.alreadyFetchedMap = {};
}

CategoryMapType.handleTileMarkerResponse = function(json) {
    if (!json[0] || !json[0][ONION_PROP_FEATURES]) {
	return;
    }
    for (var i = 0; i < json[0][ONION_PROP_FEATURES].length; i++) {
	var title = OnionLayer.featureTitle(json[0][ONION_PROP_FEATURES][i]);
	var latLng = OnionLayer.featureLatLng(json[0][ONION_PROP_BASE], json[0][ONION_PROP_FEATURES][i], map.getProjection());
	var fid = json[0].features[i].id;
	addMarker(latLng, title, fid, BACK_END);
    }
};

CategoryMapType.prototype.getTile = function(coord, zoom, ownerDocument) {
    if (bufferGlobal.pressed) {
	var img = ownerDocument.createElement('img');
	img.style.width = this.tileSize.width + 'px';
	img.style.height = this.tileSize.height + 'px';
	img.src = 'http://mt0.google.com/mapslt?lyrs=gw:direct:' + categoryString + '&x=' + coord.x + '&y=' + coord.y + '&z=' + zoom;
	var div = ownerDocument.createElement('DIV');
	div.appendChild(img);
	div.supertemp = 'temp';
	return div;
    }
};

CategoryMapType.prototype.fetchDataIfNeeded = function(event) {
    var x = Math.floor(event.point.x / 256 * Math.pow(2, map.getZoom()));
    var y = Math.floor(event.point.y / 256 * Math.pow(2, map.getZoom()));
    var z = map.getZoom();
    var key = 'x=' + x +
    ':y=' + y +
    ':z=' + z;
    if (this.alreadyFetchedMap[key]) {
	return;
    }
    this.alreadyFetchedMap[key] = 1;
    var scriptContainer = document.getElementById('ftResponse');
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = 'http://mt0.google.com/mapslt/ft?lyrs=gw:direct:' + categoryString + '&x=' + x + '&y=' + y + '&z=' + z + '&callback=CategoryMapType.handleTileMarkerResponse&output=jsonp';
    scriptContainer.appendChild(script);

	
};



function initialize() {
    locationCenter = new google.maps.LatLng(37.7699298, -122.4269157);
    zoomLevel = 17;
    var mapOptions = {
        zoom: 17,
        center: locationCenter,
        mapTypeId: google.maps.MapTypeId.ROADMAP,
        dragable: true,
        draggingCursor:'move', draggableCursor:'pointer'
    };
    map = new google.maps.Map(document.getElementById("mapCanvas"),
                              mapOptions);

    autocomplete = new google.maps.places.Autocomplete(document.getElementById('searchTextField'));
    google.maps.event.addListener(autocomplete, 'place_changed', function() {
            showSelectedPlace();
        });
    //google.maps.event.addListener(map, 'zoom_changed', updateFeaturesZoom);
    //    google.maps.event.addListener(map, 'center_changed', updateFeaturesDrag);
}

function showSelectedPlace() {
    var place = autocomplete.getPlace();
    map.panTo(place.geometry.location);
    //    getFeaturesQuery();
}

function addMarkerOn() {
        map.setOptions({draggingCursor:'crosshair', draggableCursor:'crosshair'});
    google.maps.event.addListenerOnce(map, 'click', function(event) {
         map.setOptions({draggingCursor:'move', draggableCursor:'pointer'});          
       addMarker(event.latLng);
        });
}

function addMarker(location, str, fid, flag ) {
    if(!location) 
	return;
    if (flag == BACK_END) {
	marker = new google.maps.Marker({
		position: location,
		map: map,
		draggable: true
	    });
	
	var markerImage = new google.maps.MarkerImage( imgUrl,
						      new google.maps.Size(10, 10), new google.maps.Point(0, 0), new google.maps.Point(5, 5));
	marker.setIcon(markerImage);
	marker.type = 
	marker.setTitle(str);
	marker.setDraggable(false);
	google.maps.event.addListener(marker, 'click', showDetails);

	var details = {};
	details.arrayId = markersArrayFetched.length;
	details.fid = fid;
	marker.details = details;
	markersArrayFetched.push(marker);
        
    }
    else {
        marker = new google.maps.Marker({
                position: location,
                map: map,
                draggable: true
            });
        marker.setIcon(markerUrl);    
        marker.markerId = markersArrayUser.length;
        addMarkerBackend(marker);
    }

    //attach a mouseover e

}

function addMarkerBackend(marker) {
    
    var contentString = getDivWithString("", "", "", true, false);
    var infowindow = new google.maps.InfoWindow({
	    content: contentString,
      zIndex: 10
	});

    infowindow.open(map, marker);
    google.maps.event.addListener( marker, 'click', function() {
	    infowindow.open(map, marker);
      obj.collapse(); 
      bufferGlobal.title = this.getTitle();
      bufferGlobal.phone = this.phone;
      bufferGlobal.website = this.website;
      bufferGlobal.markerId = this.markerId; 
	});
    marker.infowindow = infowindow;
    markersArrayUser.push(marker);
}

function submitFeatureDetails() {
    
    var id = markersArrayUser.length - 1;
    var lat = markersArrayUser[id].position.lat();
    var lng = markersArrayUser[id].position.lng();
    
    var markerId = markersArrayUser[id].markerId; 
    var title = document.getElementById("infoTitle").value;
    var phone = document.getElementById("infoPhone").value;
    var website = document.getElementById("infoWebsite").value;
    markersArrayUser[id].setTitle(title);
    markersArrayUser[id].phone = phone;
    markersArrayUser[id].website = website;
    markersArrayUser[id].campaignId = bufferGlobal.campaignId;
    markersArrayUser[id].infowindow.close();
    var contentString = getDivWithString(title, website, phone, false, true);
    markersArrayUser[id].infowindow.setContent(contentString);
    
    if (title != null || titile != "") {
        var params = {};
        params[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.SIGNED;
        params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.POST;
        var postData = gadgets.io.encodeValues({
                'lat' : lat,
                'lng' : lng,
                'title' : title,
                'phone' : phone,
                'website' : website,
                'campaignId' : bufferGlobal.campaignId,
                'flag' : "3",
                'markerId' : markerId });
        params[gadgets.io.RequestParameters.POST_DATA] = postData;
        var url = 'https://mapgametesting.appspot.com/getFeatures';
        gadgets.io.makeRequest(url, handlePostResponseAddFeature, params);
        obj.categories[bufferGlobal.campaignId].increaseCounter();
    }
    else {
        markersArrayUser[ id ].setMap(null);
        markersArrayUser.length = id - 1;
    }
}

function requestUserData(data) {
    var params = {};
    params[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.SIGNED;
    params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.JSON;
    var url = 'https://mapgametesting.appspot.com/getFeatures';
    gadgets.io.makeRequest(url, handleResponseUserFeatures, params);
}


function editFeatureDetails() {
    var markerId = bufferGlobal.markerId;
    markersArrayUser[markerId].setTitle(document.getElementById("infoTitle").value);  
    markersArrayUser[markerId].phone = document.getElementById("infoPhone").value;
    markersArrayUser[markerId].website = document.getElementById("infoWebsite").value;
    markersArrayUser[markerId].infowindow.close();
    var marker = markersArrayUser[markerId];
    var contentString = getDivWithString(marker.title, marker.website, marker.phone, false, true);
    markersArrayUser[markerId].infowindow.setContent(contentString);
    var params = {};
    params[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.SIGNED;
    params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.POST;
    var postData = gadgets.io.encodeValues({
            'lat' : marker.position.lat(),
            'lng' : marker.position.lng(),
            'title' : marker.getTitle(),
            'phone' : marker.phone,
            'website' : marker.website,
            'featureId' : marker.featureId,
            'markerId' : marker.markerId,
            'campaignId' : marker.campaignId,
            'flag' : "1" });
    params[gadgets.io.RequestParameters.POST_DATA] = postData;
    var url = 'https://mapgametesting.appspot.com/getFeatures';
    gadgets.io.makeRequest(url, handlePostResponseEditFeature, params);
}



function deleteFeature(marker) {
    var params = {};
    params[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.SIGNED;
    params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.POST;
    var postData = gadgets.io.encodeValues({
            'featureId' : marker.featureId,
            'flag' : "2" });
    params[gadgets.io.RequestParameters.POST_DATA] = postData;
    var url = 'https://mapgametesting.appspot.com/getFeatures';
    gadgets.io.makeRequest(url, handleResponseDeleteFeature, params);
    obj.categories[marker.campaignId].decreaseCounter();
    markersArrayUser.splice(marker.markerId,1);
}


/*
  function insertPopUpDiv() {
  var popup = document.createElement("div");
  var marker = this;
  popup.innerHTML = '<input type="text" size="20" id="editText"><br />
  <input type="button" value="Update" onlick="hideDiv(1, marker)"
  <input type="button" value="Delete" onlick="hideDiv(2, marker)"
  <input type="button" value="Cancel" onlick="hideDiv(3, marker)"';
  popup.style.z = 1000;
  popup.style.position = "absolute";
  popup.style.top = "30%";
  popup.style.left = "30%";
  popup.id = "popup";
  document.getElementById("mapCanvas").addChild(popup);
  }
*/

function clearOverlaysAll() {
    clearOverlaysArgs(markersArrayFetched);
    clearOverlaysArgs(markersArrayUser);
}

function clearOverlaysFetched() {
    clearOverlaysArgs(markersArrayFetched);
}

function clearOverlaysUser() {
    clearOverlaysArgs(markersArrayUser);
}

// Shows any overlays currently in the array
function handleSelectShow(selectObj) {
    if(selectObj.selectedIndex == 0)
        showOverlaysAll();
    else if(selectObj.selectedIndex == 1)
        showOverlaysFetched();
    else
        showOverlaysUser();
}

function showOverlaysAll() {
    showOverlaysArgs(markersArrayFetched);
    showOverlaysArgs(markersArrayUser);
}

function showOverlaysFetched() {
    showOverlaysArgs(markersArrayFetched);
}

function showOverlaysUser() {
    showOverlaysArgs(markersArrayUser);
    requestUserData();
}

// Deletes all markers in the array by removing references to them
function handleSelectDelete(selectObj) {
    if(selectObj.selectedIndex == 0)
        deleteOverlaysAll();
    else if(selectObj.selectedIndex == 1)
        deleteOverlaysFetched();
    else
        deleteOverlaysUser();
}

function deleteOverlaysAll() {
    deleteOverlaysArgs(markersArrayFetched);
    deleteOverlaysArgs(markersArrayUser);
}

function deleteOverlaysFetched() {
    deleteOverlaysArgs(markersArrayFetched);
}

function deleteOverlaysUser() {
    deleteOverlaysArgs(markersArrayUser);
}

function clearOverlaysArgs(obj) {
    if (obj.length) {
        for (i in obj) {
            obj[i].setMap(null);
        }
    }
}

function showOverlaysArgs(obj) {
    if (obj) {
        for (i in obj) {
            obj[i].setMap(map);
        }
    }
}

function deleteOverlaysArgs(obj) {
    if (obj.length) {
        for (i in obj) {
            obj[i].setMap(null);
        }
        obj.length = 0;
    }
    else
        obj = {};
}

function getFeaturesQuery() {
    if (pressed == 1 || pressed == 0) {
        var obj = {};
        obj.gw = "11";
        obj.category = "Restaurants";   //Restaurants, 991830....Cafe, 991835
        obj.ctype = "991830";
        var loc = map.getCenter();
        obj.ll = loc.lat() + "%2C" + loc.lng();
        spn.h = map.getBounds().getNorthEast().lat() - map.getBounds().getSouthWest().lat();
        spn.w = map.getBounds().getNorthEast().lng() - map.getBounds().getSouthWest().lng();
        obj.output = "jsonp";
        obj.callback = "handleResponse";
        obj.spn = spn.w + "%2C" + spn.h;
        obj.z = map.zoom;
        obj.hl = "en";
        sendRequest(obj);
    }
}

function showDetails(e) {
    var marker = this;
    var obj = {};
    obj.fid = marker.details.fid;
    obj.fid.replace(":", "%3A");
    obj.gw = 39;
    obj.output = "jsonp";
    obj.callback = "handleFeatureResponse";

    var loc = map.getCenter();
    obj.ll = loc.lat() + "%2C" + loc.lng();
    spn.h = map.getBounds().getNorthEast().lat() - map.getBounds().getSouthWest().lat();
    spn.w = map.getBounds().getNorthEast().lng() - map.getBounds().getSouthWest().lng();

    obj.spn = spn.w + "%2C" + spn.h;
    obj.z = map.zoom;
    obj.hl = "en";
    
    bufferGlobal.marker = marker;
    sendRequest(obj);
}

function sendRequest(payload) {

    var base = "http://www.google.com/mapmaker";

    var arr = [];
    var count = 0;
    for (var i in payload) {
        arr[ count ] = i + "=" + payload[ i ];
        count++;
    }

    var tmpUrl = arr.join('&');
    var url = base + "?" + tmpUrl;

    var script = document.createElement("script");
    script.setAttribute("src",url);
    script.setAttribute("type","text/javascript");
    document.body.appendChild(script);
    
}

function handlePostResponseEditFeature(response) {
    var data = JSON.parse(response.data);
    var markerId = data.markerId;
    markersArrayUser[markerId].featureId = data.featureId;
}

function handlePostResponseAddFeature(response) {
    var data = JSON.parse(response.data);
    var markerId = data.markerId;
    markersArrayUser[markerId].featureId = data.featureId;
    var contentString = getDivWithString(markersArrayUser[markerId].getTitle(), markersArrayUser[markerId].website, markersArrayUser[markerId].phone, false, true);
    markersArrayUser[markerId].infowindow.setContent(contentString);
}


function handleResponseDeleteFeature(response) {
  
}

function handleResponseUserFeatures(response) {
    var data = response.data;
    var len = data.length;
    var i, latlng;
    for (i = 0; i < len; i++) {
        latlng = new google.maps.LatLng(data[i].lat, data[i].lng);
        var marker = new google.maps.Marker({
                position: latlng,
                map: map,
                draggable: true
            });
	
	if (data[i].campaignId == "Restaurants") 
	    markerUrl = RES_USER_ICON;	
	else if (data[i].campaignId == "Cafes") {
	    markerUrl = CAFE_USER_ICON;
	}
	else if (data[i].campaignId == "Hospitals") {
	    markerUrl = HOS_USER_ICON;
	}
        
        marker.setIcon(markerUrl);
        marker.setTitle(data[i].title);
        marker.featureId = data[i].featureId;
	marker.campaignId = data[i].campaignId;
        marker.markerId = i;
        marker.phone = data[i].phone;
        marker.website = data[i].website;
        var contentString = getDivWithString(data[i].title, data[i].website, data[i].phone, false, true);
        var infowindow = new google.maps.InfoWindow({
           content: contentString,
           zIndex: 10
         });
        marker.infowindow = infowindow; 
        markersArrayUser.push(marker);
  
	google.maps.event.addListener(marker, 'click', function() {
		this.infowindow.open(map, markersArrayUser[this.markerId]);
      obj.collapse();
		bufferGlobal.title = this.getTitle();
		bufferGlobal.phone = this.phone;
		bufferGlobal.website = this.website;
		bufferGlobal.markerId = this.markerId;
		bufferGlobal.campaignId = this.campaignId;
	    });
    }
}


function handleResponse(obj) {
    var markers = obj.overlays.markers;
    var len;
    if(markers){
        for (var i = 0, len = markers.length; i < len; i++) {
            var latlng = new google.maps.LatLng(markers[i].lat, markers[i].lng);
            addMarker( latlng, markers[i].tooltip, markers[i] );
        }
    }
}

function handleFeatureResponse(objLocal) {
    var marker = bufferGlobal.marker;
    var tmp = objLocal.markers[0].laddr;
    var addr = "";
    var phone = "";
    var title;
    var i = 0;
    while(tmp[i] != "@") {
	addr = addr + tmp[i];
	i++;
    }
    tmp = objLocal.markers[0].infoWindow.basics;
    i = tmp.indexOf("Phone: ");
    if (i != -1) {
	i = i + "Phone: ".length;
	while(tmp[i] != '.') {
	    phone = phone + tmp[i];
	    i++
		}
    }
    title = marker.getTitle();
    var contentString = getDivWithString(title, addr, phone, false, false);
    var infowindow = new google.maps.InfoWindow({
	    content: contentString,
      zIndex: 10
	});

    markersArrayFetched.splice(marker.details.arrayId, 1);
    marker.setMap(null);
    var newMarker = new google.maps.Marker({
		position: marker.position,
		map: map,
		draggable: false
	    });
    var markerImage = new google.maps.MarkerImage( imgUrl,
						      new google.maps.Size(10, 10), new google.maps.Point(0, 0), new google.maps.Point(5, 5));
    newMarker.setIcon(markerImage);
    newMarker.setTitle(title);
    infowindow.open(map,newMarker);
    obj.collapse();
    google.maps.event.addListener(newMarker, 'click', function() {
	    infowindow.open(map,newMarker);
      obj.collapse(); 
	});
    markersArrayFetched.push(newMarker)
}

function handleResponseCategoryCount(response) {
    var data = response.data;
    obj.addCategory('Cafes', data[1]);
    obj.addCategory('Hospitals', data[2]);
    obj.addCategory('Restaurants', data[0]);
}


function getDivWithString(title, website, phone, flag, edit) {
    var content = "<div id='infoWindow'>";
    if (edit) {
	if (flag) {
	    content = content + createInputBox("Title", "infoTitle", 20, true, title);
	    content = content + createInputBox("Website", "infoWebsite", 20, false, website);
	    content = content + createInputBox("Phone", "infoPhone", 20, false, phone);
	    content = content + '<input type=button id=infoButton value="submit" style="float:right" onclick="editFeatureDetails()"/></div>';
	  }
	else {
	    content = content + '<h3>' + title + '</h3>' + 
		website + '<br />Phone: ' + phone + "<a style='float:right;' herf=javascript:void(0) onclick='showEditInfoData()'>Edit</a>" + 
         "<a style='float:right; padding: 0 4px 0 10px;' herf=javascript:void(0) onclick='deleteInfoData()'>Delete </a></div>";
	}
    }
    else {
	if (flag) {
	    content = content + createInputBox("Title", "infoTitle", 20, true, title);
	    content = content + createInputBox("Website", "infoWebsite", 20, false, website);
	    content = content + createInputBox("Phone", "infoPhone", 20, false, phone);
	    content = content + '<input type=button id=infoButton value="submit" style="float:right" onclick="submitFeatureDetails()"/></div>';
	}
	else {
	    content = content + '<h3>' + title + '</h3>' + 
		website + '<br />Phone: ' + phone + "</div>";
	}
    }
    return content;
}

function showEditInfoData() {
    var contentString = getDivWithString(bufferGlobal.title, bufferGlobal.website, bufferGlobal.phone, true, true );
    var markerId = bufferGlobal.markerId;
    markersArrayUser[markerId].infowindow.setContent(contentString);
}

function deleteInfoData() {
  var markerId = bufferGlobal.markerId;
  markersArrayUser[markerId].infowindow.close();
  markersArrayUser[markerId].setMap(null);
  deleteFeature(markersArrayUser[markerId]);
}


function createInputBox(name, id, size, heading, value) {
    var str = "";
    if (heading) {
      str = "<div style='padding: 10px 0 0 0;'><label style='float:left;font-weight:bold;padding: 0 15px 0 0;'>"
	  + name + "</label><input style='float:right' type=text id='" + id + "'size='" + size + "' value = '" + 
	  value + "'/></div><br clear=all />";
    }
    else {
      str = "<div style='padding: 4px 0 0 0;'><label style='float:left;padding: 0 15px 0 0;'>"+ 
	  name + "</label><input style='float:right' type=text id='" + id + "'size='" + 
	  size + "' value = '" + value + "'/></div><br clear=all />";
    }
    return str;
}

function updateFeaturesDrag() {
    spn.h = map.getBounds().getNorthEast().lat() - map.getBounds().getSouthWest().lat();
    spn.w = map.getBounds().getNorthEast().lng() - map.getBounds().getSouthWest().lng();

    var diffX, diffY;
    diffX = Math.abs( locationCenter.lng() - map.getCenter().lng() );
    diffY = Math.abs( locationCenter.lat() - map.getCenter().lat() );

    var maxW = parseInt( document.getElementById("mapCanvas").getBoundingClientRect().width );
    var maxH = parseInt( document.getElementById("mapCanvas").getBoundingClientRect().height );

    diffX = maxW * (diffX / spn.w);
    diffY = maxH * (diffY / spn.h);

    var dist = Math.sqrt( diffX*diffX + diffY*diffY );
    var maxDist = Math.sqrt( maxW*maxW + maxH*maxH );

    var ratio = dist / maxDist;
    //  console.log(ratio);
    if(ratio > 0.1 && map.zoom >= 16 ) {
        getFeaturesQuery();
        locationCenter = map.getCenter();
    }

}

function updateFeaturesZoom() {
    if(map.getZoom() < 16){
        document.getElementById("zoomChanged").innerHTML = "Please zoom in to view marked places";
    }
    else if((zoomLevel - map.getZoom()) > 0 || (map.getZoom() == 16)){
        getFeaturesQuery();
        zoomLevel = map.getZoom();
        document.getElementById("zoomChanged").innerHTML = "";
    }
    else{
        zoomLevel = map.getZoom();
    }
}



function init() {
    // TODO: Write the code for initializing.
    gadgets.window.adjustHeight(600);
    
    var params = {};
    params[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.SIGNED;
    params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.JSON;
    var url = 'https://mapgametesting.appspot.com/getNumberOfFeatures'; 
    gadgets.io.makeRequest(url, handleResponseCategoryCount, params);
    requestUserData();

    initialize();
    initFooter();   
   // initLhp();
    obj = new ManageMarkers();
}

gadgets.util.registerOnLoadHandler(init);
// TODO: Write the code for Canvas view.